﻿
function Deploy-AppOffline
{
        [cmdletbinding(SupportsShouldProcess=$true)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [ValidateScript({Test-Path $_ -PathType Container})] 
        [String] 
        $toolsFolder,

        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [ValidateScript({Test-Path $_ -PathType Container})] 
        [String] 
        $targetFolder

        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Deploy-AppOffline from $toolsFolder to $targetFolder"
    }
    End
    {
        write-verbose "End Deploy-AppOffline from $toolsFolder to $targetFolder"
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {

        $appOfflinePath = Join-Path $toolsFolder -ChildPath "App_Offline.htm"
        $logoPath = Join-Path $toolsFolder -ChildPath "LogoUBP.png"         
        
        if (Test-Path -Path $appOfflinePath)
        {
            write-verbose "Copy $appOfflinePath to $targetFolder"
            Copy-Item -Path $appOfflinePath -Destination $targetFolder
        }
        else
        {
            write-verbose "$appOfflinePath doesn't exist"        
        }
        
        if (Test-Path -Path $logoPath)
        {
            write-verbose "Copy $logoPath to $targetFolder"
            Copy-Item -Path $logoPath -Destination $targetFolder
        }
        else
        {
            write-verbose "$logoPath doesn't exist"                
        }
        
    }

}


function Remove-AppOffline
{
        [cmdletbinding(SupportsShouldProcess=$true)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [ValidateScript({Test-Path $_ -PathType Container})] 
        [String] 
        $targetFolder

        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Remove-AppOffline from $targetFolder"
    }
    End
    {
        write-verbose "End Remove-AppOffline from $targetFolder"
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {

        $appOfflinePath = Join-Path $targetFolder -ChildPath "App_Offline.htm"
        $logoPath = Join-Path $targetFolder -ChildPath "LogoUBP.png"         
        
        if (Test-Path -Path $appOfflinePath)
        {
            write-verbose "Remove $appOfflinePath"        
            Remove-Item -Path $appOfflinePath
        }
        else
        {
            write-verbose "$appOfflinePath doesn't exist"        
        }
        
        if (Test-Path -Path $logoPath)
        {
            write-verbose "Remove $logoPath"        
            Remove-Item -Path $logoPath
        }
        else
        {
            write-verbose "$logoPath doesn't exist"                
        }
        
    }

}




function Lock-WebApplication
{
        [cmdletbinding(SupportsShouldProcess=$True)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [String] 
        $ConfigurationPath,

        [Parameter(Mandatory=$false,ValueFromPipeline=$true)] 
        [String[]] 
        $IpExclusions

        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Lock-WebApplication $ConfigurationPath"
        if ($IpExclusions -and ($IpExclusions.Count -gt 0))
        {
            write-verbose "Allowed ip are $($IpExclusions -join ', ')"
        } 
    }
    End
    {
        write-verbose "End Lock-WebApplication $ConfigurationPath"
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {
        
        try
        {
            if ($PSCmdlet.ShouldProcess("Lock web Application Access for this website '$($configurationPath)' but exclude these ip '$($IpExclusions -join ', ')'"))
            {
                
                #Lock Web site access
                &C:\Windows\System32\inetsrv\appcmd.exe set config $ConfigurationPath -section:system.webServer/security/ipSecurity /allowUnlisted:false
                if ($LASTEXITCODE -gt 0) 
                {
                    throw New-Object System.InvalidOperationException "Configuration path $ConfigurationPath doesn't exist"
                }

                #Allow ips to access to this site during lock 
                if ($IpExclusions -and ($IpExclusions.Count -gt 0))
                {
                    foreach($ip in $IpExclusions)
                    {
                        [System.Net.IPAddress]$checkIp=$null
                        if ([System.Net.IPAddress]::TryParse($ip, [ref]$checkIp))
                        {
                            $blockIp="system.webServer/security/ipSecurity /+[ipAddress='$($Ip)',allowed='true']"
                            Write-Verbose "Add allowed adress $blockIp"
                            &C:\Windows\System32\inetsrv\appcmd.exe set config $ConfigurationPath -section:$blockIp
                            if ($LASTEXITCODE -gt 0) 
                            {
                                throw New-Object System.InvalidOperationException "Unable to allow this $ip in the section"
                            }
                        }
                        else
                        {
                            Write-Warning "Ip $ip can't add to exclusion list because it's not a valid Ip Adress"
                        }
                    }#end ip exclusion browsing

                }#end ip exlcusion test
                
                &C:\Windows\System32\inetsrv\appcmd.exe set config $ConfigurationPath -section:system.webServer/security/ipSecurity /commit:app

            }#end should process
        }
        Catch [Exception]
        {
            write-Error "Error Lock-WebApplication : $($_.Exception.Message)"
        }

    }

}


function Unlock-WebApplication
{
        [cmdletbinding(SupportsShouldProcess=$True)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [String] 
        $ConfigurationPath

        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Unlock-WebApplication $ConfigurationPath"
        
    }
    End
    {
        write-verbose "End Unlock-WebApplication $ConfigurationPath"
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {
        
        try
        {
            if ($PSCmdlet.ShouldProcess("Unlock web Application Access for this website '$($configurationPath)'"))
            {
                &C:\Windows\System32\inetsrv\appcmd.exe set config $ConfigurationPath -section:system.webServer/security/ipSecurity /allowUnlisted:true
                if ($LASTEXITCODE -gt 0) 
                {
                    throw New-Object System.InvalidOperationException "Configuration path $ConfigurationPath doesn't exist"
                }

                [xml]$configSection = &C:\Windows\System32\inetsrv\appcmd.exe list config $ConfigurationPath -section:system.webServer/security/ipSecurity -xml

                $IpAdress = $configSection.appcmd.CONFIG.SelectNodes("//add")
                if ($IpAdress -and ($IpAdress.Count -gt 0))
                {
                    foreach($result in $IpAdress)
                    {

                        $blockIp="system.webServer/security/ipSecurity /-[ipAddress='$($result.ipAddress)']"
                        Write-Verbose "Remove ip adress $blockIp"
                        &C:\Windows\System32\inetsrv\appcmd.exe set config $ConfigurationPath -section:$blockIp
                        if ($LASTEXITCODE -gt 0) 
                        {
                            Write-Error "Unable to allow this $result.ipAddress in the section"
                        }
                    }#end ip exlcusion browsing
                }#end ip exlcusions test to remove
                &C:\Windows\System32\inetsrv\appcmd.exe set config $ConfigurationPath -section:system.webServer/security/ipSecurity /commit:app
            }#end should process

        }
        Catch [Exception]
        {
            write-Error "Error Unlock-WebApplication : $($_.Exception.Message)"
        }

    }

}


function Set-LockErrorPage
{
        [cmdletbinding(SupportsShouldProcess=$True)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [String] 
        $ConfigurationPath,

        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [ValidateScript({Test-Path $_ -PathType Leaf -ErrorAction Stop})] 
        [String] 
        $errorPagePath
        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Set-LockErrorPage $ConfigurationPath with this page $errorPagePath when Http error=403.6"
        
    }
    End
    {
        write-verbose "End Set-LockErrorPage $ConfigurationPath with this page $errorPagePath when Http error=403.6"
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {
        
        try
        {
            if ($PSCmdlet.ShouldProcess("Set Error page '$($errorPagePath)' for this website '$($configurationPath)' when Http error=403.6"))
            {
                $lockErrorPageConfiguration = "system.webServer/httpErrors /+[statusCode='403',subStatusCode='6',responseMode='File',path='$errorPagePath']"
                &C:\Windows\System32\inetsrv\appcmd.exe set config $ConfigurationPath -section:$lockErrorPageConfiguration /commit:app
                if ($LASTEXITCODE -gt 0) 
                {
                    throw New-Object System.InvalidOperationException "Configuration path $ConfigurationPath doesn't exist"
                }
            }
        }
        catch [exception]
        {
             write-Error "Error Set-LockErrorPage : $($_.Exception.Message)"
        }
    }
}


function Remove-LockErrorPage
{
        [cmdletbinding(SupportsShouldProcess=$True)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [String] 
        $ConfigurationPath       
        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Remove-LockErrorPage for this web site $ConfigurationPath when Http error=403.6"
        
    }
    End
    {
        write-verbose "End Remove-LockErrorPage for this web site $ConfigurationPath when Http error=403.6"
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {
        
        try
        {
            if ($PSCmdlet.ShouldProcess("Remove Error page for code 403.6 for this website '$($configurationPath)'"))
            {
                $lockErrorPageConfiguration = "system.webServer/httpErrors /-[statusCode='403',subStatusCode='6',path='c:\tempygo.png',responseMode='File']"
                &C:\Windows\System32\inetsrv\appcmd.exe set config $ConfigurationPath -section:$lockErrorPageConfiguration /commit:app
                if ($LASTEXITCODE -gt 0) 
                {
                    throw New-Object System.InvalidOperationException "Configuration path $ConfigurationPath doesn't exist"
                }
            }
        }
        catch [exception]
        {
             write-Error "Error Remove-LockErrorPage : $($_.Exception.Message)"
        }
    }
}


function Backup-ApplicationPools
{
        [cmdletbinding(SupportsShouldProcess=$True)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [ValidateScript({Test-Path $_ -PathType Container})] 
        [String] 
        $Destination,
        
        [Parameter(Mandatory=$false)] 
        [switch]
        $KeepPreviousBackup,

        [Parameter(Mandatory=$false)] 
        [Int32]
        $NumberOfkeepPreviousBackup = 2        
        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Backup-ApplicationPools to $destination"        
    }
    End
    {
        write-verbose "End Backup-ApplicationPools to $destination"
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {                
        #Check Target Folder : We start from its parent
        $destinationFolder = [System.IO.Path]::Combine($destination, "ApplicationPools")
        if (Test-Path $destinationFolder)
        {
            if ($keepPreviousBackup)
            {
                Write-Verbose "Found previous backup and keep them"
            }
            else
            {
                Write-Verbose "Found previous backup $($itemSource.Name) and delete them from $destinationFolder"
                Delete-Folders -source $destinationFolder -pattern "*"                    
            }
        }

        #Create the destination Folder before if it doesn't exist                
        if ((Test-Path $destinationFolder) -eq $false)
        {
			Write-verbose "Create destination folder $destinationFolder before copy"
            New-Item -Path $destinationFolder -ItemType Container
        }
        
        #Backup the folder
		Write-verbose "backup application pools configuration to $destinationFolder"
        
        #Calculate destination path archive file name
        $archiveFileName = "AppPoolConfiguration_" + $(Get-Date -Format "yyyyMMdd_hhmmss") + ".zip"
        $archiveFilePath = Join-Path -Path $destinationFolder -ChildPath $archiveFileName
        
        
        #Call msdeploy to synchronize package with destination
        Write-Warning "TODO : Change password management !!"
		$commandToExecute = '& "C:\Program Files\IIS\Microsoft Web Deploy V2\msdeploy.exe" -verb:sync -source:"{0}" -dest:"{1}"'
		$sourceProvider="appPoolConfig"
		$destinationProvider=[System.String]::Format("package='{0}',encryptpassword='secret'",$archiveFilePath)
		
        $commandToExecute = [System.String]::Format($commandToExecute, $sourceProvider, $destinationProvider)
    
    
         #Add whatif support
        if($PSBoundParameters['Whatif'])
        {
            $commandToExecute += " -Whatif"
        }
        
        Write-verbose "Command to execute : $commandToExecute"
        Invoke-Command -ScriptBlock ([scriptblock]::create($commandToExecute))
        
    }
}


function Install-IIS7ApplicationPool
{
        [cmdletbinding(SupportsShouldProcess=$True)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [ValidateScript({Test-Path $_ -PathType Container})] 
        [String] 
        $Path,
        
        [Parameter(Mandatory=$true)] 
        [String] 
        $appPoolName,
        
        [Parameter(Mandatory=$false)] 
        [String] 
        $PackageName = "IISConfiguration",
		
        [Parameter(Mandatory=$false)] 
        [String] 
        $appPoolTemplateFileName="appPoolConfig.zip"
		        
        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Install-IIS7ApplicationPool $Name from $Path"        
    }
    End
    {
        write-verbose "End Install-IIS7ApplicationPool $Name from $Path"        
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {                
    
        #Find package in Path directory
        $package = Get-ChildItem -Path $Path -Recurse -Filter $PackageName
        
        if ($package -eq $null)
        {
            throw New-Object System.Exception "NO package $PackageName!!!"
        }

        #Test appPool Template configuration file
        $appPoolTemplateFilePath = Join-Path -Path $package.Fullname -ChildPath $appPoolTemplateFileName
        if ((Test-Path -Path $appPoolTemplateFilePath) -eq $false)
		{
            throw New-Object System.Exception "Application pool Template file $appPoolTemplateFileName is missing"
		}	

		#Search application pool according its name
        $appPoolConfigurationFilePath = Join-Path -Path $package.FullName -ChildPath "$appPoolName.xml"
        if ((Test-Path -Path $appPoolConfigurationFilePath) -eq $false)
		{
            throw New-Object System.Exception "Application pool configuration file $appPoolConfigurationFilePath is missing"
		}	
        
		Write-verbose "Install application pools $appPoolName with configuration file $appPoolConfigurationFilePath and template  $appPoolTemplateFilePath"
        
		#Call msdeploy to synchronize package with destination
		Write-Warning "TODO : Change password management !!"
		$commandToExecute = '& "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:"{0}" -dest:"{1}" -setParamFile={2}'
		$sourceProvider=[System.String]::Format("package='{0}',encryptpassword='secret.1'",$appPoolTemplateFilePath)        
		$destinationProvider=[System.String]::Format("appPoolConfig='{0}'",$appPoolName)
		$setParamFile=[System.String]::Format("{0}",$appPoolConfigurationFilePath)
		
		$commandToExecute = [System.String]::Format($commandToExecute, $sourceProvider, $destinationProvider, $setParamFile)
    
		 #Add whatif support
		if($PSBoundParameters['Whatif'])
		{
			$commandToExecute += " -Whatif"
		}			
		Write-verbose "Command to execute : $commandToExecute"
		Invoke-Command -ScriptBlock ([scriptblock]::create($commandToExecute))
			
        
    }
}

function Install-IIS6ApplicationPool
{
        [cmdletbinding(SupportsShouldProcess=$True)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [ValidateScript({Test-Path $_ -PathType Container})] 
        [String] 
        $Path,
        
        [Parameter(Mandatory=$true)] 
        [String] 
        $appPoolName,
        
        [Parameter(Mandatory=$false)] 
        [String] 
        $PackageName = "IISConfiguration",
		
        [Parameter(Mandatory=$false)] 
        [String] 
        $appPoolTemplateFileName="IIS6appPoolConfig.zip"
		        
        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Install-IIS6ApplicationPool $Name from $Path"        
    }
    End
    {
        write-verbose "End Install-IIS6ApplicationPool $Name from $Path"        
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {                
    
        #Find package in Path directory
        $package = Get-ChildItem -Path $Path -Recurse -Filter $PackageName
        
        if ($package -eq $null)
        {
            throw New-Object System.Exception "NO package $PackageName!!!"
        }

        #Test appPool Template configuration file
        $appPoolTemplateFilePath = Join-Path -Path $package.Fullname -ChildPath $appPoolTemplateFileName
        if ((Test-Path -Path $appPoolTemplateFilePath) -eq $false)
		{
            throw New-Object System.Exception "Application pool Template file $appPoolTemplateFileName is missing"
		}	

		#Search application pool according its name
        $appPoolConfigurationFilePath = Join-Path -Path $package.FullName -ChildPath "$appPoolName.xml"
        if ((Test-Path -Path $appPoolConfigurationFilePath) -eq $false)
		{
            throw New-Object System.Exception "Application pool configuration file $appPoolConfigurationFilePath is missing"
		}	
        
		Write-verbose "Install application pools $appPoolName with configuration file $appPoolConfigurationFilePath and template  $appPoolTemplateFilePath"
        
		#Call msdeploy to synchronize package with destination
		Write-Warning "TODO : Change password management !!"
		$commandToExecute = '& "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:"{0}" -dest:"{1}" -setParamFile={2}'
		$sourceProvider=[System.String]::Format("package='{0}',encryptpassword='secret.1'",$appPoolTemplateFilePath)        
		$destinationProvider=[System.String]::Format("metaKey='/LM/W3SVC/AppPools/{0}'",$appPoolName)
		$setParamFile=[System.String]::Format("{0}",$appPoolConfigurationFilePath)
		
		$commandToExecute = [System.String]::Format($commandToExecute, $sourceProvider, $destinationProvider, $setParamFile)
    
		 #Add whatif support
		if($PSBoundParameters['Whatif'])
		{
			$commandToExecute += " -Whatif"
		}			
		Write-verbose "Command to execute : $commandToExecute"
		Invoke-Command -ScriptBlock ([scriptblock]::create($commandToExecute))
			
        
    }
}


function Install-IIS7ApplicationFromTemplate
{
        [cmdletbinding(SupportsShouldProcess=$True)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [ValidateScript({Test-Path $_ -PathType Container})] 
        [String] 
        $Path,
        
        [Parameter(Mandatory=$true)] 
        [String] 
        $applicationPath,
        
        [Parameter(Mandatory=$false)] 
        [String] 
        $applicationParameterFileName,
        
        [Parameter(Mandatory=$false)] 
        [String] 
        $PackageName = "IISConfiguration",
		
        [Parameter(Mandatory=$false)] 
        [String] 
        $applicationTemplateFileName="appHostConfig.zip"
		        
        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Install-IIS7ApplicationFromTemplate $applicationPath from $Path"        
    }
    End
    {
        write-verbose "End Install-IIS7ApplicationFromTemplate $applicationPath from $Path"        
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {                
    
        #Find package in Path directory
        $package = Get-ChildItem -Path $Path -Recurse -Filter $PackageName
        
        if ($package -eq $null)
        {
            throw New-Object System.Exception "NO package $PackageName!!!"
        }

        #Test application Template configuration file
        $applicationTemplateFilePath = Join-Path -Path $package.Fullname -ChildPath $applicationTemplateFileName
        if ((Test-Path -Path $applicationTemplateFilePath) -eq $false)
		{
            throw New-Object System.Exception "Application Template file $applicationTemplateFilePath is missing"
		}	

		#Search application configuration file according its name
        if ([System.String]::IsNullOrEmpty($applicationParameterFileName))
        {
            write-verbose "Application parameter file is null, get parameter file from application Path $applicationPath"
            $applicationParameterFileName = $applicationPath.Replace("/","_")    
            Write-Verbose "Application parameter file is $applicationParameterFileName"
        }
        
        $applicationConfigurationFilePath = Join-Path -Path $package.FullName -ChildPath "$applicationParameterFileName.xml"
        if ((Test-Path -Path $applicationConfigurationFilePath) -eq $false)
		{
            throw New-Object System.Exception "Application configuration file $applicationConfigurationFilePath is missing"
		}	
        
		Write-verbose "Install application $applicationPath with configuration file $applicationConfigurationFilePath and template $applicationTemplateFileName"
        
		#Call msdeploy to synchronize package with destination
		Write-Warning "TODO : Change password management !!"
		$commandToExecute = '& "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:"{0}" -dest:"{1}" -setParamFile={2}'
		$sourceProvider=[System.String]::Format("package='{0}'",$applicationTemplateFilePath)        
		$destinationProvider=[System.String]::Format("appHostConfig='{0}'",$applicationPath)
		$setParamFile=[System.String]::Format("{0}",$applicationConfigurationFilePath)
		
		$commandToExecute = [System.String]::Format($commandToExecute, $sourceProvider, $destinationProvider, $setParamFile)
    
		 #Add whatif support
		if($PSBoundParameters['Whatif'])
		{
			$commandToExecute += " -Whatif"
		}			
		Write-verbose "Command to execute : $commandToExecute"
		Invoke-Command -ScriptBlock ([scriptblock]::create($commandToExecute))
			
        
    }
}

function Install-IIS7Application
{
        [cmdletbinding(SupportsShouldProcess=$True)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [ValidateScript({Test-Path $_ -PathType Container})] 
        [String] 
        $Path,
        
        [Parameter(Mandatory=$true)] 
        [String] 
        $applicationPath,
        
        [Parameter(Mandatory=$true)] 
        [String] 
        $PhysicalApplicationPath,
        
        [Parameter(Mandatory=$true)] 
        [String] 
        $ApplicationPool,
        
        [Parameter(Mandatory=$false)] 
        [String] 
        $PackageName = "IISConfiguration",
		
        [Parameter(Mandatory=$false)] 
        [String] 
        $applicationTemplateFileName="appHostConfig.zip"
		        
        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Install-IIS7Application $applicationPath from $Path"        
    }
    End
    {
        write-verbose "End Install-IIS7Application $applicationPath from $Path"        
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {                
    
        #Find package in Path directory
        $package = Get-ChildItem -Path $Path -Recurse -Filter $PackageName
        
        if ($package -eq $null)
        {
            throw New-Object System.Exception "NO package $PackageName!!!"
        }

        #Test application Template configuration file
        $applicationTemplateFilePath = Join-Path -Path $package.Fullname -ChildPath $applicationTemplateFileName
        if ((Test-Path -Path $applicationTemplateFilePath) -eq $false)
		{
            throw New-Object System.Exception "Application Template file $applicationTemplateFilePath is missing"
		}	

		Write-verbose "Install application $applicationPath from template $applicationTemplateFileName"
        
		#Call msdeploy to synchronize package with destination
		Write-Warning "TODO : Change password management !!"
		$commandToExecute = '& "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:"{0}" -dest:"{1}" -setParam:"{2}" -setParam:"{3}"'
		$sourceProvider=[System.String]::Format("package='{0}'",$applicationTemplateFilePath)        
		$destinationProvider=[System.String]::Format("appHostConfig='{0}'",$applicationPath)
		$setParam1=[System.String]::Format("name='physicalPathLocation',value='{0}'",$PhysicalApplicationPath)
		$setParam2=[System.String]::Format("name='applicationPool',value='{0}'",$ApplicationPool)
		
		$commandToExecute = [System.String]::Format($commandToExecute, $sourceProvider, $destinationProvider, $setParam1, $setParam2)
    
		 #Add whatif support
		if($PSBoundParameters['Whatif'])
		{
			$commandToExecute += " -Whatif"
		}			
		Write-verbose "Command to execute : $commandToExecute"
		Invoke-Command -ScriptBlock ([scriptblock]::create($commandToExecute))
			
        
    }
}

function Install-IIS6Application
{
        [cmdletbinding(SupportsShouldProcess=$True)]
        Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 
        [ValidateScript({Test-Path $_ -PathType Container})] 
        [String] 
        $Path,
        
        [Parameter(Mandatory=$true)] 
        [String] 
        $applicationPath,
        
        [Parameter(Mandatory=$true)] 
        [String] 
        $PhysicalApplicationPath,
        
        [Parameter(Mandatory=$true)] 
        [String] 
        $ApplicationPool,
        
        [Parameter(Mandatory=$false)] 
        [String] 
        $PackageName = "IISConfiguration",
		
        [Parameter(Mandatory=$false)] 
        [String] 
        $applicationTemplateFileName="IIS6application.zip"
		        
        )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew() 
        write-verbose "Start Install-IIS6Application $applicationPath from $Path"        
    }
    End
    {
        write-verbose "End Install-IIS6Application $applicationPath from $Path"        
        $watch.Stop();
        Write-Verbose "Function duration : $($watch.Elapsed)"
    }
    Process
    {                
    
        #Find package in Path directory
        $package = Get-ChildItem -Path $Path -Recurse -Filter $PackageName
        
        if ($package -eq $null)
        {
            throw New-Object System.Exception "NO package $PackageName!!!"
        }

        #Test application Template configuration file
        $applicationTemplateFilePath = Join-Path -Path $package.Fullname -ChildPath $applicationTemplateFileName
        if ((Test-Path -Path $applicationTemplateFilePath) -eq $false)
		{
            throw New-Object System.Exception "Application Template file $applicationTemplateFilePath is missing"
		}	

		Write-verbose "Install application $applicationPath from template $applicationTemplateFileName"
        
		#Call msdeploy to synchronize package with destination
		Write-Warning "TODO : Change password management !!"
		$commandToExecute = '& "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:"{0}" -dest:"{1}" -setParam:"{2}" -setParam:"{3}"'
		$sourceProvider=[System.String]::Format("package='{0}'",$applicationTemplateFilePath)        
		$destinationProvider=[System.String]::Format("metakey='{0}'",$applicationPath)
		$setParam1=[System.String]::Format("name='physicalPathLocation',value='{0}'",$PhysicalApplicationPath)
		$setParam2=[System.String]::Format("name='applicationPool',value='{0}'",$ApplicationPool)
		
		$commandToExecute = [System.String]::Format($commandToExecute, $sourceProvider, $destinationProvider, $setParam1, $setParam2)
    
		 #Add whatif support
		if($PSBoundParameters['Whatif'])
		{
			$commandToExecute += " -Whatif"
		}			
		Write-verbose "Command to execute : $commandToExecute"
		Invoke-Command -ScriptBlock ([scriptblock]::create($commandToExecute))
			
        
    }
}
